﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Data.SqlClient;
using Ashlen.Portal.Core;
using Ashlen.Portal.Core.DataInterfaces;
using Ashlen.Portal.Data.SqlServer;
using System.Net.Mail;

namespace Ashlen.Utility.Mail
{
    public static class MailUtility
    {
        private static readonly IUtilityDao _utility = new UtilityDao();

        public static void ProcessMailQueue()
        {
            try
            {
                List<system_Email> emails = _utility.GetUnprocessedEmails(100) as List<system_Email>;
                MailMessage message = null;
                string[] addresses = null;
                bool sendEmail = false;
                foreach (system_Email email in emails)
                {
                    message = new MailMessage();
                    if (email.To != null)
                    {
                        sendEmail = true;
                        addresses = email.To.Split(';');
                        foreach (var toAddress in addresses)
                        {
                            message.To.Add(new MailAddress(toAddress));
                        }
                    }
                    if (email.CC != null && email.CC != string.Empty)
                    {
                        sendEmail = true;
                        addresses = email.CC.Split(';');
                        foreach (var ccAddress in addresses) {
                            message.CC.Add(new MailAddress(ccAddress));
                        }
                    }
                    if (email.BCC != null && email.BCC != string.Empty) {
                        sendEmail = true;
                        addresses = email.BCC.Split(';');
                        foreach (var bccAddress in addresses) {
                            message.Bcc.Add(new MailAddress(bccAddress));
                        }
                    }
                    if (sendEmail != false)
                    {
                        message.From = new MailAddress(email.From);
                        message.Sender = new MailAddress(email.From);
                        message.IsBodyHtml = email.IsHtml;
                        message.Subject = email.Subject;
                        message.Body = email.Body;
                        message.SubjectEncoding = System.Text.Encoding.UTF8;
                        try
                        {
                            var smtpClient = new SmtpClient()
                                                 {
                                                     Host = _utility.GetConfig(Constants.APPLICATION, "SmtpServer"),
                                                     Credentials = new NetworkCredential(_utility.GetConfig(Constants.APPLICATION, "SmtpUser"),
                                                         _utility.GetConfig(Constants.APPLICATION, "SmtpPassword"))
                                                 };
                            int port = 25;
                            int.TryParse(_utility.GetConfig(Constants.APPLICATION, "SmtpPort"), out port);
                            smtpClient.Port = port;
                            
                            bool ssl = false;
                            bool.TryParse(_utility.GetConfig(Constants.APPLICATION, "SmtpUseSSL"), out ssl);
                            smtpClient.EnableSsl = ssl;
                            smtpClient.Send(message);
                            _utility.UpdateEmailStatus(email.ID, EmailStatus.Sent, string.Empty);
                        }
                        catch (SmtpException sEx)
                        {
                            var status = EmailStatus.Sent;

                            switch (sEx.StatusCode)
                            {
                                case SmtpStatusCode.InsufficientStorage:
                                    status = email.system_EmailStatus.ID != EmailStatus.FailedCanRetry.ToString() ? EmailStatus.FailedCanRetry : EmailStatus.RetryFailed;
                                    break;
                                case SmtpStatusCode.GeneralFailure:
                                default:
                                    status = EmailStatus.Fail;
                                    break;

                            }
                            _utility.UpdateEmailStatus(email.ID, status, sEx.ToString());
                        }
                        catch (Exception ex)
                        {
                            _utility.UpdateEmailStatus(email.ID, EmailStatus.Fail, ex.ToString());
                        }
                    }
                    else
                    {
                        _utility.UpdateEmailStatus(email.ID, EmailStatus.Fail, "There were no To, CC or BCC addresses.");
                    }
                }
            }
            catch (SqlException sEx)
            {
                throw new ApplicationException("Database connection failed. Check your database settings.");
            }
        }
    }
}
